package org.vaadin.smartgwt.client.ui.tree; import org.vaadin.smartgwt.client.core.JSON; import org.vaadin.smartgwt.client.core.PaintableListListener; import org.vaadin.smartgwt.client.core.PaintablePropertyUpdater; import org.vaadin.smartgwt.client.core.PaintableReferenceListener; import org.vaadin.smartgwt.client.core.VBaseClass; import org.vaadin.smartgwt.client.core.VJSObject; import org.vaadin.smartgwt.client.ui.utils.PainterHelper; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.smartgwt.client.core.DataClass; import com.smartgwt.client.data.DataSource; import com.smartgwt.client.util.JSOHelper; import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler; import com.smartgwt.client.widgets.grid.events.SelectionEvent; import com.smartgwt.client.widgets.grid.events.SelectionUpdatedEvent; import com.smartgwt.client.widgets.grid.events.SelectionUpdatedHandler; import com.smartgwt.client.widgets.tree.Tree; import com.smartgwt.client.widgets.tree.TreeGrid; import com.smartgwt.client.widgets.tree.TreeGridField; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; public class VTreeGrid extends TreeGrid implements Paintable { protected final PaintablePropertyUpdater propertyUpdater = new PaintablePropertyUpdater(); private final Element element = DOM.createDiv(); protected String pid; protected ApplicationConnection client; protected ServerSideEventRegistration selectedChangedEventRegistration; protected ServerSideEventRegistration selectionUpdatedEventRegistration; public VTreeGrid() { propertyUpdater.addPaintableReferenceListener("data", new PaintableReferenceListener() { @Override public void onChange(Paintable paintable) { setData(((VBaseClass<Tree>) paintable).getJSObject()); } }); propertyUpdater.addPaintableListListener("fields", new PaintableListListener() { @Override public void onAdd(Paintable[] source, Integer index, Paintable element) { setFields(toTreeGridFieldArray(source)); } @Override public void onRemove(Paintable[] source, Integer index, Paintable element) { setFields(toTreeGridFieldArray(source)); } private TreeGridField[] toTreeGridFieldArray(Paintable[] source) { final TreeGridField[] fields = new TreeGridField[source.length]; for (int i = 0; i < source.length; i++) { fields[i] = ((VTreeGridField) source[i]).getJSObject(); } return fields; } }); } @Override public Element getElement() { return element; } @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if (uidl.hasAttribute("cached")) { return; } if (this.pid == null) { this.pid = uidl.getId(); this.client = client; addSelectionUpdatedHandler(new SelectionUpdatedHandler() { @Override public void onSelectionUpdated(SelectionUpdatedEvent event) { final JavaScriptObject selectedRecordsJSA = toJSOArray(getSelectedRecords()); JavaScriptObject newExclusionReplacer = JSON.newExclusionReplacer(new String[] { "children", "^_parent_isc_Tree_[0-9]+", "selections", "messages" }); VTreeGrid.this.client.updateVariable(pid, "selectedRecords", JSON.stringify(selectedRecordsJSA, newExclusionReplacer), false); } }); selectedChangedEventRegistration = new ServerSideEventRegistration("*hasSelectionChangedHandlers") { @Override protected HandlerRegistration registerHandler() { return addSelectionChangedHandler(new SelectionChangedHandler() { @Override public void onSelectionChanged(SelectionEvent event) { final JavaScriptObject eventJSO = JavaScriptObject.createObject(); JSOHelper.setAttribute(eventJSO, "record", toJSO(event.getRecord())); JSOHelper.setAttribute(eventJSO, "state", event.getState()); JSOHelper.setAttribute(eventJSO, "selection", toJSOArray(event.getSelection())); JSOHelper.setAttribute(eventJSO, "selectedRecord", toJSO(event.getSelectedRecord())); VTreeGrid.this.client .updateVariable( pid, "onSelectionChanged.event", JSON.stringify(eventJSO, JSON.newExclusionReplacer(new String[] { "children", "^_parent_isc_Tree_[0-9]+", "selections", "messages" })), true); } }); } }; selectionUpdatedEventRegistration = new ServerSideEventRegistration("*hasSelectionUpdatedHandlers") { @Override protected HandlerRegistration registerHandler() { return addSelectionUpdatedHandler(new SelectionUpdatedHandler() { @Override public void onSelectionUpdated(SelectionUpdatedEvent event) { VTreeGrid.this.client.updateVariable(pid, "onSelectionUpdated.event", true, true); } }); } }; } selectedChangedEventRegistration.updateFromUIDL(uidl); selectionUpdatedEventRegistration.updateFromUIDL(uidl); propertyUpdater.updateFromUIDL(uidl, client); if (uidl.hasAttribute("dataSource")) { final Paintable paintable = uidl.getPaintableAttribute("dataSource", client); setDataSource(((VJSObject<DataSource>) paintable).getJSObject()); } PainterHelper.updateSmartGWTComponent(client, this, uidl); } private static JavaScriptObject toJSOArray(DataClass[] array) { final JavaScriptObject arrayJSO = JavaScriptObject.createArray(); for (int i = 0; i < array.length; i++) { JSOHelper.setArrayValue(arrayJSO, i, array[i].getJsObj()); } return arrayJSO; } private static JavaScriptObject toJSO(DataClass dataClass) { return dataClass == null ? null : dataClass.getJsObj(); } private static abstract class ServerSideEventRegistration { private final String uidlAttribute; private HandlerRegistration registration; public ServerSideEventRegistration(String uidlAttribute) { this.uidlAttribute = uidlAttribute; } public void updateFromUIDL(UIDL uidl) { if (uidl.hasAttribute(uidlAttribute) && registration == null) { registration = registerHandler(); } else if (!uidl.hasAttribute(uidlAttribute) && registration != null) { registration.removeHandler(); registration = null; } } protected abstract HandlerRegistration registerHandler(); } }